package com.lty.jeeg.server.common.utils;

import com.lty.jeeg.server.common.annotation.FieldName;
import com.lty.jeeg.server.common.constant.SysConstant;
import org.dozer.DozerBeanMapper;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author LTY
 */
public class BeanConverter {

    private static DozerBeanMapper map = new DozerBeanMapper();

    /**
     * @Description 将目标对象转换为指定对象，相同属性名进行属性值复制
     * @author LTY
     * @date 2019-1-21 11:24:22
     */
    @SuppressWarnings("unchecked")
    public static <T> T map(Object source, Class<T> clazz){
        if (source==null) {
            return null;
        }
        return map.map(source, clazz);
    }

    /**
     * @Description 两个对象之间相同属性名的属性值复制
     * @author LTY
     * @date 2019-1-21 11:25:28
     */
    public static void map(Object source,Object target){
        map.map(source, target);
    }

    /**
     * @Description 对象集合中对象相同属性名的属性值复制
     * @author LTY
     * @date 2019-1-21 11:25:28
     */
    @SuppressWarnings("unchecked")
    public static List mapList(List source, Class cls){
        List listTarget = new ArrayList();
        if(source != null){
            for (Object object : source) {
                Object objTarget = BeanConverter.map(object, cls);
                listTarget.add(objTarget);
            }
        }
        return listTarget;
    }

    public static Map<String,Object> obj2Map(Object obj){
        Map<String,Object> reMap = new HashMap<>();
        if (obj == null) {
            return null;
        }
        Field[] fields = getFields(obj);
        try {
            for (Field field : fields) {
                String fieldName = field.getName();
                if (!"serialVersionUID".equals(fieldName)) {
                    Field f = getField(obj, fieldName);
                    Object o = null;
                    if (f != null) {
                        f.setAccessible(true);
                        o = f.get(obj);
                        if (o != null && o.getClass().equals(Date.class)) {
                            o = DateUtils.formatDateTime((Date) o);
                        }
                        if (f.getAnnotation(FieldName.class) != null) {
                            reMap.put(f.getAnnotation(FieldName.class).value()
                                            + SysConstant.LEFT_SQUARE_BRACKETS
                                            + fieldName
                                            + SysConstant.RIGHT_SQUARE_BRACKETS,
                                    o);
                        } else {
                            reMap.put(fieldName, o);
                        }

                    }
                }
            }
        } catch (NullPointerException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return reMap;
    }

    public static Field[] getFields(Object obj) {

        List<Field> fieldList = new ArrayList<>() ;
        Class tempClass = obj.getClass();
        //当父类为null的时候说明到达了最上层的父类(Object类).
        while (tempClass != null && tempClass != Object.class) {
            fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            //得到父类,然后赋给自己
            tempClass = tempClass.getSuperclass();
        }

        return fieldList.toArray(new Field[fieldList.size()]);
    }

    public static Field getField(Object obj, String fieldName) {
        Class tempClass = obj.getClass();
        Field field;
        while (tempClass != null && tempClass != Object.class) {
            try {
                field = tempClass.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                tempClass = tempClass.getSuperclass();
                continue;
            }
            return field;
        }
        return null;
    }
}
